/******************************************************************************
 *        
 * MODULE NAME:    sys_irq.c
 * PROJECT CODE:   BlueStream
 * DESCRIPTION:    Hardware Interrupt Interface - Chimera
 * MAINTAINER:     Ivan Griffin/Cyril Jean
 * DATE:           09 August 1999
 *
 * SOURCE CONTROL: $Id: sys_irq.c,v 1.102 2009/04/28 16:08:51 morrisc Exp $
 *
 * LICENSE:
 *     This source code is copyright (c) 2000-2004 Ceva Inc.
 *     All rights reserved.
 *
 * REVISION HISTORY:
 *    09 Aug 1999 -   IG       -  Initial Version
 *    Oct 2000    -   CJ       -  Port to Chimera
 *
 ******************************************************************************/
#include "include.h"
#include "sys_config.h"
#include "sys_types.h"
#include "sys_features.h"
#include "sys_config.h"
#include "sys_power.h"
#include "sys_irq.h"
#include "lc_types.h"
#include "lslc_slot.h"
#include "lslc_irq.h"
#include "hw_jalapeno.h"
#include "hw_register.h"
#include "hw_macro_defs.h"
#include "sys_mmi.h"
#include "tra_hcit.h"
#include "lmp_config.h"
#include "DeviceBtj_Header.h"
#include "gatt_service_hid.h"

#ifndef __USE_INLINES__
#include "sys_irq_chimera_impl.h"
#endif


extern t_LMconfig g_LM_config_info;


#define IRQ_VECTOR (unsigned *)   0x18 
#define FIQ_VECTOR (unsigned *)   0x1c
#define MASK_24_BIT         0xff000000
#define BRANCH_OP_CODE      0xea000000

#define PIPE_OFFSET               0x08
#define WORD_OFFSET               0x02

/******************************************************************************
 *
 * Module variables
 *
 ******************************************************************************/
#if (PRH_BS_DEV_USE_DELAYED_SERVICE_ROUTINES == 1)
#define DSRS_TABLE_SIZE		10

static volatile u_int32 pending_dsr_counter;
static volatile u_int32 dsr_lock;
static volatile u_int32 dsr_table_head;
static volatile u_int32 dsr_table_tail;

static void (*pending_dsr_table[DSRS_TABLE_SIZE])(void);
#endif

volatile u_int8 b_gpio_intr = 0;
extern volatile u_int8 flag_system_active;
extern volatile u_int8 flag_key_down;
extern volatile u_int8 b_26M_colsed;
 extern void latency_gpio_wakeup(void);
/******************************************************************************
 *
 * FUNCTION:  SYSirq_IRQ_Handler
 * PURPOSE:   Services slow interrupt requests to micro-controller
 *
 ******************************************************************************/
void FAST_CALL _SYSirq_FIQ_Handler(void)//FIQ_Exception(void) 
{
    unsigned int IntStat ;
    
    
    
    IntStat = REG_AHB0_ICU_INT_STATUS_FLAG;
    
#if(CEVA_CLK_16M_TO_32K)
    if(b_26M_colsed)
    {
        REG_APB5_GPIO_WUATOD_ENABLE = 0;
        REG_APB5_GPIO_WUE_ENABLE=0;  
        REG_APB5_GPIO_WUATOD_STAT = 0xffffffff;
        REG_APB5_GPIO_WUE_STAT = 0xff ;
        REG_AHB0_ICU_INT_ENABLE &= ~(INT_STATUS_GPIO|INT_STATUS_GPIO_WAKEUP);
        key_wakeup_set();
    }
#else        
 	if(b_26M_colsed)
    {   
        REG_AHB0_ICU_DIGITAL_PWD =0x00;
        DEBUG_MSG(0XA2);

        delay_us(800);         

        
        REG_APB5_GPIO_WUATOD_ENABLE = 0;
        REG_APB5_GPIO_WUE_ENABLE=0;
        
        REG_APB5_GPIO_WUATOD_STAT = 0xffffffff;
        REG_APB5_GPIO_WUE_STAT = 0xff ;
        REG_AHB0_ICU_INT_ENABLE &= ~(INT_STATUS_GPIO|INT_STATUS_GPIO_WAKEUP);
        key_wakeup_set();
        DEBUG_MSG(0XA3);
        Set_CPU_PLL_clk(1);
        delay_us(60);
        sys_wakeup();
        DEBUG_MSG(0XA4);
        BK3000_XVR_REG_0x0A = XVR_ANALOG_REG_BAK[10] = 0xC0016208;
        delay_us(10);
        REG_AHB0_ICU_CEVA_CLKCON=0x00;
        delay_us(1);
        REG_AHB0_DCO16M_PWD 	 = 0x01 ;
        delay_us(1);
    }
#endif		
    if(IntStat & INT_STATUS_CEVA) 
    {  
        LSLCirq_IRQ_Handler();  
    }

    if(IntStat & INT_STATUS_GPIO)           //GPIO Int Assert
    { 
        DEBUG_MSG(0XA7);
        
        sys_flag |= FLAG_GPIO_INTERRPUT;
        
        key_process();
        
        SYSpwr_Handle_Early_Wakeup();
      
        latency_gpio_wakeup();
        sys_flag &= ~FLAG_GPIO_INTERRPUT;
        DEBUG_MSG(0XA8);
    }    
    if(IntStat & INT_STATUS_UART)          //Uart1 Int Assert
    {
        UART_Interrupt_Handler();
    }
    REG_AHB0_ICU_INT_STATUS_FLAG= IntStat;
}
//=======================================================================
//=======================================================================
void _SYSirq_IRQ_Handler(void)//IRQ_Exception(void)
{
    unsigned int IntStat;
    
    IntStat = REG_AHB0_ICU_INT_STATUS_FLAG;
    
   
    if(IntStat & INT_STATUS_TIMER)
    {
        Timer_ISR();
    }
    
    if(IntStat & INT_STATUS_RTC)           //RTC Int Assert
    {
//        Beken_RTC_IntService();
    } 
    if(IntStat & INT_STATUS_PWM)
    {
//        Beken_PWM_IntService();
    }
    if(IntStat & INT_STATUS_ADC)            //ADC Int Assert
    {
        sys_flag |= FLAG_ADC_BUZY;
        REG_APB7_ADC_CFG |= (1<<BIT_ADC_INT_CLEAR);
//        Beken_ADC_IntService();
    }
    
    if(IntStat & INT_STATUS_EXT_TIME)      //External Timer (Sub-DeepSleep Timer) Int Assert
    {
//        SubDeepSleep_Timer_IntService();
    }

    if(IntStat & INT_STATUS_I2C)           //I2c1 Int Assert
    {
        //BKI2cIntService(0);
    }

    if(IntStat & INT_STATUS_SPI)           //Spi1 Int Assert
    {
        //BKSpiIntService(0);
    }

    REG_AHB0_ICU_INT_STATUS_FLAG= IntStat;
}

#pragma ARM
/*Do not change the function*/

__IRQ__ void FAST_ENTRY1 SYSirq_FIQ_Handler(void)
{

	__asm volatile
	{
		bl _SYSirq_FIQ_Handler
	};
}


__IRQ__ void FAST_ENTRY2 SYSirq_IRQ_Handler(void)
{

	__asm volatile
	{
		bl _SYSirq_IRQ_Handler
	};
}


/******************************************************************************
 *
 * FUNCTION:  SYSirq_Disable_Interrupts_Save_Flags
 * PURPOSE:   Disables ARM IRQ and FIQ Interrupts, saves previous
 *            PSR
 *
 ******************************************************************************/
void SYSirq_Disable_Interrupts_Save_Flags(u_int32 *flags)
{
	   #pragma arm
#ifndef __GNUC__
    u_int32 current_flags,my_tmp_flags;
    __asm
    {
	    MRS current_flags, CPSR                 /* Get current CPSR */
        AND my_tmp_flags, current_flags, #0xc0  /* Clear all ex. IRQ and FIQ */
        STR my_tmp_flags, [flags]               /* "save" flags */
#if (PRH_BS_DEV_UART_FIQ_ALWAYS_ENABLED==1)
        ORR current_flags, current_flags, #0x80 /* Disable IRQ Only */
#else
        ORR current_flags, current_flags, #0xc0 /* Disable IRQ and FIQ */
#endif
        MSR CPSR_c, current_flags                 /* Write back */
    }
#else
    /* GNU C inline asm? */
#endif
}

void SYSirq_Disable_Interrupts_Only_IRQ_Save_Flags(u_int32 *flags)
{
	   #pragma arm
#ifndef __GNUC__
    u_int32 current_flags,my_tmp_flags;
    __asm
    {
	MRS current_flags, CPSR                 /* Get current CPSR */
        AND my_tmp_flags, current_flags, #0xc0  /* Clear all ex. IRQ and FIQ */
        STR my_tmp_flags, [flags]               /* "save" flags */

        ORR current_flags, current_flags, #0x80 /* Disable IRQ Only */

        MSR CPSR_c, current_flags                 /* Write back */
    }
#else
    /* GNU C inline asm? */
#endif
}

/******************************************************************************
 *
 * FUNCTION:  SYSirq_Enable_Interrupts_Save_Flags
 * PURPOSE:   Enables ARM IRQ and FIQ Interrupts, saves previous
 *            PSR
 *
 ******************************************************************************/
void SYSirq_Enable_Interrupts_Save_Flags(u_int32 *flags)
{
	   #pragma arm
#ifndef __GNUC__
    u_int32 current_flags,my_tmp_flags;
    __asm
    {
	    MRS current_flags, CPSR                 /* Get current CPSR */
        AND my_tmp_flags, current_flags, #0xc0  /* Clear all ex. IRQ and FIQ */
        STR my_tmp_flags, [flags]               /* "save" flags */
        AND current_flags, current_flags, #0x3f /* Enable IRQ and FIQ */
        MSR CPSR_c, current_flags                 /* Write back */
    }
#else
    /* GNU C inline asm? */
#endif
}

/******************************************************************************
 *
 * FUNCTION:  SYSirq_Interrupts_Restore_Flags
 * PURPOSE:   Restores previously saved previous PSR
 *
 ******************************************************************************/
void SYSirq_Interrupts_Restore_Flags(u_int32 flags)
{
	#pragma arm 
#ifndef __GNUC__
    u_int32 current_flags;
    __asm
    {
        MRS current_flags, CPSR                 /* Get current CPSR */
        BIC current_flags, current_flags, #0xc0 /* Clear IRQ and FIQ bits */
        ORR current_flags, current_flags, flags /* OR in saved copy */
        MSR CPSR_c, current_flags                 /* Write back */
    }
#else
    /* GNU C inline asm? */
#endif

}



/******************************************************************************
 *
 * FUNCTION:  SYSirq_Initialise
 * PURPOSE:   Initialise Interrupt Requests
 *
 ******************************************************************************/
void SYSirq_Initialise(void)
{
    /*
     * Intialise interrupts
     */
#if (PRH_BS_DEV_USE_DELAYED_SERVICE_ROUTINES == 1)
    dsr_table_head = 0;
    dsr_table_tail = 0;
    
    pending_dsr_counter = 0;
    dsr_lock = 0;
#endif
    /* SYSirq_IRQ_Disable_All(); - now done in BT_Init */
     /*
      * Install Service Routines
      */
	_SYSirq_Setup_IRQ_FIQ_Enable_Masks();
	

}


/******************************************************************************
 *
 * FUNCTION:  SYSirq_Disable_Baseband_ISR_Save_Flags
 * PURPOSE:   Disables ARM IRQ Baseband_ISR, saves previous
 *            PSR
 *
 ******************************************************************************/
void SYSirq_Disable_Baseband_ISR_Save_Flags(u_int32 *flags)
{
	  #pragma arm
#ifndef __GNUC__
    u_int32 current_flags,my_tmp_flags;
    __asm
    {
	       MRS current_flags, CPSR                 /* Get current CPSR */
        AND my_tmp_flags, current_flags, #0xC0  /* Clear all ex. IRQ and FIQ */
        STR my_tmp_flags, [flags]               /* "save" flags */
        ORR current_flags, current_flags, #0x80 /* Disable IRQ and FIQ */
        MSR CPSR_c, current_flags                 /* Write back */
    }
#else
    /* GNU C inline asm? */
#endif
}

/******************************************************************************
 *
 * FUNCTION:  SYSirq_Enable_Baseband_ISR_Save_Flags
 * PURPOSE:   Enables ARM IRQ Baseband_ISR, saves previous
 *            PSR
 *
 ******************************************************************************/
void SYSirq_Enable_Baseband_ISR_Save_Flags(u_int32 *flags)
{
	   #pragma arm
#ifndef __GNUC__
    u_int32 current_flags,my_tmp_flags;
    __asm
    {
	MRS current_flags, CPSR                 /* Get current CPSR */
        AND my_tmp_flags, current_flags, #0xC0  /* Clear all ex. IRQ and FIQ */
        STR my_tmp_flags, [flags]               /* "save" flags */
        AND current_flags, current_flags, #0x7f /* Enable IRQ and FIQ */
        MSR CPSR_c, current_flags                 /* Write back */
    }
#else
    /* GNU C inline asm? */
#endif
}

/******************************************************************************
 *
 * FUNCTION:  SYSirq_Baseband_ISR_Restore_Flags
 * PURPOSE:   Restores previously saved previous PSR
 *
 ******************************************************************************/
void SYSirq_Baseband_ISR_Restore_Flags(u_int32 flags)
{
	   #pragma arm
#ifndef __GNUC__
    u_int32 current_flags;
    __asm
    {
        MRS current_flags, CPSR                 /* Get current CPSR */
        BIC current_flags, current_flags, #0x80 /* Clear IRQ and FIQ bits */
        ORR current_flags, current_flags, flags /* OR in saved copy */
        MSR CPSR_c, current_flags                 /* Write back */
    }
#else
    /* GNU C inline asm? */
#endif
}









